/**
 * Created with JetBrains WebStorm.
 * User: Ender
 * Date: 6/2/13
 * Time: 5:50 PM
 */

'use strict';

angular.module('ender.boardgames.tictactoe', [])
    .factory('ticTacToeGame', function () {

        var customRules = [
            {
                id: "boardSize",
                name: "Board size",
                type: "number",
                default: 3
            }
        ];

        var boardSize = {
            size: null
        };

        return {
            name: "Tic-Tac-Toe : X - 0",
            customRules: customRules,
            boardSize: boardSize,
            preProcessBoard: function () {
                // nothing to do here
            },
            processRules: function (rules) {
                rules = rules || customRules;

                var ruleValues = {};
                for (var i = 0; i < rules.length; i++) {
                    var gameRule = rules[i];
                    ruleValues[gameRule.id] = gameRule.value || gameRule.default;
                }

                boardSize.size = ruleValues.boardSize;
            },
            processPlayers: function (players) {
                players[0].symbol = 'X';
                players[1].symbol = '0';
            },
            checkVictory: function (board, players, currentPlayer) {
                var length = board.length;

                // check rows
                for (var i = 0; i < length; i++) {
                    var row = board[i];
                    // check against first value
                    var firstValueInRow = row[0].symbol;
                    // if nothing in first cell, the row can't be full
                    if (!firstValueInRow)
                        continue;
                    // go through the cells in the row
                    var rowFullSame = true;
                    for (var c = 1; c < length && rowFullSame; c++) {
                        var cell = row[c];
                        if (cell.symbol != firstValueInRow) {
                            rowFullSame = false;
                        }
                    }
                    if (rowFullSame)
                        return true;
                }

                // check columns
                for (var columnCounter = 0; columnCounter < length; columnCounter++) {
                    // check against first value
                    var firstValueInColumn = board[0][columnCounter].symbol;
                    // if nothing in first cell, the row can't be full
                    if (!firstValueInColumn)
                        continue;
                    // go through the cells in the column
                    var columnFullSame = true;
                    for (var rowCounter = 1; rowCounter < length && columnFullSame; rowCounter++) {
                        var cell = board[rowCounter][columnCounter];
                        if (cell.symbol != firstValueInColumn) {
                            columnFullSame = false;
                        }
                    }
                    if (columnFullSame)
                        return true;
                }

                // check descending (first) diagonal
                var firstValueInDescendingDiagonal = board[0][0].symbol;
                if (firstValueInDescendingDiagonal) {
                    var diagonalSame = true;
                    for (var diagonalCounter = 1; diagonalCounter < length && diagonalSame; diagonalCounter++) {
                        var cell = board[diagonalCounter][diagonalCounter];
                        if (cell.symbol != firstValueInDescendingDiagonal) {
                            diagonalSame = false;
                        }
                    }
                    if (diagonalSame)
                        return true;
                }

                // check descending (second) diagonal
                var firstValueInAscendingDiagonal = board[0][length - 1].symbol;
                if (firstValueInAscendingDiagonal) {
                    var diagonalSame = true;
                    for (var rowCounter = 1, columnCounter = length - 2; rowCounter < length && diagonalSame; rowCounter++, columnCounter--) {
                        var cell = board[rowCounter][columnCounter];
                        if (cell.symbol != firstValueInAscendingDiagonal) {
                            diagonalSame = false;
                        }
                    }
                    if (diagonalSame)
                        return true;
                }

                var boardIsFull = true;
                boardIsFullLabel:
                    for (var i = 0; i < length; i++) {
                        for (var j = 0; j < length; j++) {
                            var cell = board[i][j];
                            if (!cell.symbol) {
                                boardIsFull = false;
                                break boardIsFullLabel;
                            }
                        }
                    }
                if (boardIsFull) {
                    return 'draw';
                }

                return false;
            },
            processCellClicked: function (board, row, column, currentPlayer) {
                board[row][column].symbol = currentPlayer.symbol;
            },
            isLegalMove: function (board, row, column) {
                return !board[row][column].symbol;
            },
            getClassForCell: function () {
                return 'end-boardgame-tictactoe-cell';
            },
            getClassForPlayerIndicator: function () {
                return 'end-boardgame-tictactoe-player-indicator';
            }
        }
    })
    .directive('endBoardgameTictactoeCell', function factoryFunction() {
        return {
            restrict: 'C',
            link: function (scope, element, attrs) {
                scope.$watch('cell.symbol', function (newSymbol, oldSymbol) {
                    if (newSymbol !== oldSymbol) {
                        if (newSymbol)
                            element.html(newSymbol);
                        else
                            element.html('');
                    }
                });
            }
        };
    })
    .directive('endBoardgameTictactoePlayerIndicator', function factoryFunction() {
        return {
            restrict: 'C',
            link: function (scope, element, attrs) {
                scope.$watch('player.symbol', function (newSymbol, oldSymbol) {
                    if (newSymbol)
                        element.html(newSymbol);

                });
            }
        }
    });